package nachos.threads;

import java.util.*;

public abstract class WorldStateListener {

   public static ArrayList<WorldStateListener> listeners 
      = new ArrayList<WorldStateListener>();

   static int childOahu      = 0;
   static int childMolokai   = 0;
   static int adultOahu      = 0;
   static int adultMolokai   = 0;

   protected int OAHU = Boat.OAHU;
   protected int MOLOKAI = Boat.MOLOKAI;

   protected int island = OAHU;

   public WorldStateListener() {
      listeners.add( this );
      if (this instanceof Child)
          childOahu++;
      if (this instanceof Adult)
          adultOahu++;
      System.out.println( "Children " + childOahu );
      System.out.println( "Adults " + adultOahu );
      System.out.println( "Children2 " + childMolokai );
      System.out.println( "Adults2 " + adultMolokai );
   }

   public String certainties() {
      String ret = "";
      if( this instanceof Adult ) {
         ret += "Adult ";
      } else if( this instanceof Child ) {
         ret += "Child ";
      }

      if( island == OAHU ) {
         ret += "on OAHU, ";
      } else {
         ret += "on MOLOKAI, ";
      }

      if( Boat.side() == OAHU ) {
         ret += "boat: OAHU";
      } else {
         ret += "boat: MOLOKAI";
      }

      if( boatIsEmpty() ) {
         ret += " [empty]";
      } else {
         ret += " [non-empty]";
      }
      return ret;
   }
   
   /**
    * @return true if at least one child is present on Molokai
    */
   protected boolean childOnMolokai() {
      return (childMolokai> 0);
   }

   /**
    * @return true if the boat is currently empty
    */
   protected boolean boatIsEmpty() {
      return Boat.isEmpty();
   }

   public void addListener( WorldStateListener l ) {
      listeners.add( l );
   }
   
   /**
    * reset values for new simulation
    */
   static void reset() {
      childOahu = 0;
      adultOahu = 0;
      childMolokai = 0;
      adultMolokai = 0;
   }

   /**
    * move boat to other island
    */
   public void cross() {
      handleCross( island, this instanceof Child );
      Boat.cross();
   }

   /**
    * @return true if there are people left on Oahu
    */
   public boolean shouldRun() {
      boolean ret = true;
      //There are no adults or children left that need to cross
      if (childOahu == 0 && adultOahu == 0){
         ret = false;
      }
      return ret;
   }

   /**
    * adjust counters when people cross to the other island
    */
   public void handleCross( int from, boolean child ) {
      //for( int i=0; i<listeners.size(); i++ ) {
         if( from == OAHU && child ) {
            childMolokai++;
            childMolokai++;
            if( childOahu > 0 ) {
               childOahu--;
               childOahu--;
            }
         } else if( from == OAHU ) {
            adultMolokai++;
            if( adultOahu > 0 ) {
               adultOahu--;
            }
         } else if( from == MOLOKAI && child ) {
            childOahu++;
            if( childMolokai > 0 ) {
               childMolokai--;
            }
         } else {
            adultOahu++;
            if( adultMolokai > 0 ) {
               adultMolokai--;
            }
         }
      //}
   }
}
